package main

import (
	"bytes"
	"errors"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

var buffer bytes.Buffer
//转移文件
//读取目录
//文本替换
func main()  {

	http.HandleFunc("/hook", sayhelloName) //设置访问的路由
	err := http.ListenAndServe(":9911", nil) //设置监听的端口
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}

}

func sayhelloName(w http.ResponseWriter, r *http.Request) {
	pass:=r.Header.Get("X-Gitee-Token")
	if pass!="123456" {
		fmt.Println("异常请求",pass)
		return
	}

	fmt.Println("删除_book")
	run("rm","-rf","/home/yc/gitbook/yc-book/_book")

	//buf,_:=run("git","-C","/home/yc/gitbook/yc-book/","checkout","--","_book")
	fmt.Println("拉取最新代码")
	run("git","-C","/home/yc/gitbook/yc-book/","pull")
	fmt.Println("安装gitbook插件")
	run("gitbook","install","/home/yc/gitbook/yc-book/")
	fmt.Println("编译gitbook")
	run("gitbook","build","/home/yc/gitbook/yc-book/")
	//转移文件
	fmt.Println("首页文件转移开始")
	copyFile("/home/yc/gitbook/yc-book/yc-index/index.html","/home/yc/gitbook/yc-book/_book/index.html")
	fmt.Println("首页文件转移完毕")
	fmt.Println("首页文件夹转移开始")
	run("cp","-ri","/home/yc/gitbook/yc-book/yc-index/yc_resource","/home/yc/gitbook/yc-book/_book/gitbook/")
	fmt.Println("首页文件夹转移完毕")
	buffer.WriteString("首页文件夹转移完毕\n")

	files, _ := ioutil.ReadDir("/home/yc/gitbook/yc-book/_book")
	strs:= map[string]string{}
	for _, f := range files {
		if f.IsDir() {
			if f.Name()=="gitbook" {
				continue
			}
			if f.Name()=="yc-index" {
				continue
			}
			strs[f.Name()]=Capitalize(f.Name())
		}
	}
	buffer.WriteString("文本替换开始\n")

	fmt.Println("文本替换开始")
	sayHi(strs)
	fmt.Println("文本替换结束")
	buffer.WriteString("文本替换结束\n")

	fmt.Fprintf(w,buffer.String())
}

func sayHi(strs map[string]string) error {
	var str string
	for key,value:=range strs{
		str+="<li><a href='"+key+"/"+"'>"+value+"</a></li>"
	}
	fmt.Println(str)
	// 解析指定文件生成模板对象
	tem,err := template.ParseFiles("/home/yc/gitbook/yc-book/_book/index.html")
	if err != nil{
		fmt.Println("读取文件失败,err",err)
		return err
	}
	f,_:=os.Create("/home/yc/gitbook/yc-book/_book/index.html")

	// 利用给定数据渲染模板，并将结果写入w
	return tem.Execute(f,template.HTML(str))
}


/**
 * 拷贝文件夹,同时拷贝文件夹中的文件
 * @param srcPath  		需要拷贝的文件夹路径: D:/test
 * @param destPath		拷贝到的位置: D:/backup/
 */
func CopyDir(srcPath, destPath string) error {
	//检测目录正确性
	if srcInfo, err := os.Stat(srcPath); err != nil {
		fmt.Println(err.Error())
		return err
	} else {
		if !srcInfo.IsDir() {
			e := errors.New("srcPath不是一个正确的目录！")
			fmt.Println(e.Error())
			return e
		}
	}
	if destInfo, err := os.Stat(destPath); err != nil {
		fmt.Println(err.Error())
		return err
	} else {
		if !destInfo.IsDir() {
			e := errors.New("destInfo不是一个正确的目录！")
			fmt.Println(e.Error())
			return e
		}
	}
	//加上拷贝时间:不用可以去掉
	//destPath = destPath + "_" + time.Now().Format("20060102150405")

	err := filepath.Walk(srcPath, func(path string, f os.FileInfo, err error) error {
		if f == nil {
			return err
		}
		if !f.IsDir() {
			path := strings.Replace(path, "\\", "/", -1)
			destNewPath := strings.Replace(path, srcPath, destPath, -1)
			copyFile(path, destNewPath)
		}
		return nil
	})
	if err != nil {
		fmt.Println("复制文件:失败")
		fmt.Printf(err.Error())
	}
	return err
}

//生成目录并拷贝文件
func copyFile(src, dest string) (w int64, err error) {
	srcFile, err := os.Open(src)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	defer srcFile.Close()
	//分割path目录
	destSplitPathDirs := strings.Split(dest, "/")

	//检测时候存在目录
	destSplitPath := ""
	for index, dir := range destSplitPathDirs {
		if index < len(destSplitPathDirs)-1 {
			destSplitPath = destSplitPath + dir + "/"
			createDir(destSplitPath)
		}
	}
	dstFile, err := os.Create(dest)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	defer dstFile.Close()

	return io.Copy(dstFile, srcFile)
}

//检测文件夹路径时候存在
func pathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// Capitalize 字符首字母大写
func Capitalize(str string) string {
	var upperStr string
	vv := []rune(str)   // 后文有介绍
	for i := 0; i < len(vv); i++ {
		if i == 0 {
			if vv[i] >= 97 && vv[i] <= 122 {  // 后文有介绍
				vv[i] -= 32 // string的码表相差32位
				upperStr += string(vv[i])
			} else {
				fmt.Println("Not begins with lowercase letter,")
				return str
			}
		} else {
			upperStr += string(vv[i])
		}
	}
	return upperStr
}

func run(name string, arg ...string) ([]byte,bool) {
	cmd := exec.Command(name, arg...)
	buf, err := cmd.Output()
	if err != nil {
		buffer.WriteString(name+"::命令执行输出失败")
		fmt.Println(name+"::命令执行输出失败"+err.Error())
		return nil,false
	}
	return buf,true
}

func createDir(destSplitPath string)  {
	b, _ := pathExists(destSplitPath)
	if b == false {
		fmt.Println("创建目录:" + destSplitPath)
		//创建目录
		err := os.Mkdir(destSplitPath, os.ModePerm)
		if err != nil {
			fmt.Println(err)
		}
	}
}
